import os
import sys
Import('env')
env['CPU'] = 'cortex-m0'
env['LLVM_CFG'] = 'armv6m_soft_nofp_nosys.cfg'

def plf_postaction(self,target):
    if 'progen' in self['TOOLS']:
        return
    self.AddPostAction(target,Action('$OBJDUMP -d -z -x $TARGET > ${TARGET.base}.asm'))
    target_path = str(target[0]).replace('.elf','')
    app_hex = self.Command(target_path+'.hex',target[0],Action('$OBJCOPY -O ihex $SOURCES $TARGET'))
    self.AddPostAction(target[0],Action('$OBJCOPY -O binary $TARGET ${TARGET.base}.ota.bin'))
    info_sbl_hex = self.Command('build/le501x/info_sbl.hex',self.subst('$SDK_ROOT/soc/arm_cm/le501x/bin/bram.bin'),Action(self.subst('python $SDK_ROOT/tools/le501x/info_sbl_merge.py') + ' $SOURCE $APP_IMAGE_BASE $TARGET'))
    if self.get('STACK_HEX') is None:
        production_hex_depends = [info_sbl_hex,app_hex]
    else:
        production_hex_depends = [info_sbl_hex,app_hex,self['STACK_HEX']]
    self.Command(target_path+'_production.hex',production_hex_depends, Action(self.subst('python $SDK_ROOT/tools/hexmerge.py') + ' $SOURCES > $TARGET'))



def plf_build(self,name,app_src,rtos,with_startup,ble,mesh,objprefix):
    start_src = []
    if with_startup:
        start_src = ['$SDK_ROOT/soc/arm_cm/le501x/compiler/$COMPILER/startup.S']
    sdk_src = []
    sdk_src += list(map(lambda x:os.path.join('$SDK_ROOT/soc/',x),[
        'arm_cm/svcall.c',
        'arm_cm/systick.c',
        'arm_cm/swint_handler.c',
        'arm_cm/le501x/cpu.c',
        'arm_cm/le501x/platform.c',
        'arm_cm/le501x/stack_var.c',
        'arm_cm/le501x/compiler/$COMPILER/sleep_asm.S',
        'arm_cm/le501x/compiler/$COMPILER/svcall_asm.S',
        'arm_cm/le501x/compiler/$COMPILER/delay_asm.S',
        'arm_cm/le501x/integration/lsqspi_msp.c',
        'arm_cm/le501x/integration/uart_msp.c',
        'arm_cm/le501x/integration/spi_msp.c',
        'arm_cm/le501x/integration/adc_msp.c',
        'arm_cm/le501x/integration/i2c_msp.c',
        'arm_cm/le501x/integration/modem_rf_le501x.c',
        'arm_cm/le501x/integration/modem_rf_le501x_24g.c',
        'arm_cm/le501x/integration/calc_acc.c',
        'arm_cm/le501x/integration/lscache_msp.c',
        'arm_cm/le501x/integration/io_config.c',
        'arm_cm/le501x/integration/dmac_msp.c',
        'arm_cm/le501x/integration/lspdm_msp.c',
        'arm_cm/le501x/integration/lsiwdg_msp.c',
        'arm_cm/le501x/integration/rtc_msp.c',
        'arm_cm/le501x/integration/lstimer_msp.c',
        'arm_cm/le501x/integration/ssi_msp.c',
        'arm_cm/le501x/integration/trng_msp.c',
        'arm_cm/le501x/integration/lspis_msp.c',
        'arm_cm/le501x/integration/lscrypt_msp.c',
        'arm_cm/le501x/integration/lsecc_msp.c',
        'arm_cm/le501x/sleep.c',
        'arm_cm/le501x/sys_stat.c',
        'arm_cm/le501x/sw_timer_port.c',
    ]))
    sdk_src += list(map(lambda x:os.path.join('$SDK_ROOT/peripheral/',x),[
        'src/flash_svcall.c',
        'src/adc_dma.c',
        'src/calc_div.c',
        'src/dmac.c',
        'src/lsadc.c',
        'src/lscache.c',
        'src/lscrypt.c',
        'src/lsi2c.c',
        'src/lsiwdg.c',
        'src/lspdm_dma.c',
        'src/lspdm.c',
        'src/lspis.c',
        'src/lsqspi.c',
        'src/lsrtc.c',
        'src/lsspi_dma.c',
        'src/lsspi.c',
        'src/lsssi_dma.c',
        'src/lsssi.c',
        'src/lstimer.c',
        'src/lstrng.c',
        'src/spi_flash_lsqspi.c',
        'src/spi_flash.c',
        'src/uart_dma.c',
        'src/uart.c',
        'src/lsecc.c',
    ]))
    sdk_src += list(map(lambda x:os.path.join('$SDK_ROOT/module/',x),[
        'common/common.c',
        'common/circular_doubly_linked_list.c',
        #'common/linked_async_framework.c',
        #'common/async_call.c',
        'common/sw_timer.c',
        #'calendar/calendar.c',
        'crc/crc16.c',
        'debug/log.c',
        'debug/ls_dbg.c',
        'debug/$BASE_ARCH/$COMPILER/ls_dbg_asm.S',
        'debug/RTT/SEGGER_RTT.c',
        'static_buffer/linked_buffer.c',
        'static_buffer/fifo.c',
        'tinyfs/tinyfs_nvm.c',
        'tinyfs/tinyfs_write_cache.c',
        'tinyfs/tinyfs.c',
        'tinycrypt/lib/source/sha256.c',
        'tinycrypt/lib/source/utils.c',
        #'adpcm/adpcm.c',
        #'micro-ecc/uECC.c',
        'ble/ble_common_api.c',
        'settings/inflash_settings.c',
        'settings/ota_settings.c',
    ]))
    inc_list = list(map(lambda x:os.path.join('$SDK_ROOT/',x),['peripheral/inc',
        'peripheral/api',
        'module/common',
        #'module/calendar',
        'module/crc',
        'module/debug',
        'module/debug/RTT',
        'module/static_buffer',
        'module/tinyfs',
        'module/tinycrypt/lib/include',
        #'module/micro-ecc',
        #'module/adpcm',
        'module/ble',
        'module/ble/prf',
        'module/settings',
        'soc',
        'soc/arm_cm',
        'soc/arm_cm/cmsis',
        'soc/arm_cm/le501x',
        'soc/arm_cm/le501x/integration',
    ]))
    rtos_src = []
    if not rtos is None:
        rtos_src = list(map(lambda x:os.path.join('$SDK_ROOT/rtos/freertos/',x),[
            'croutine.c',
            'event_groups.c',
            'list.c',
            'queue.c',
            'stream_buffer.c',
            'tasks.c',
            'timers.c',
            'heap_4.c',
        ]))
        if ble:
            rtos_adapt = 'arm_cm/le501x/freertos_adapt_ble.c'
        else:
            rtos_adapt = 'arm_cm/le501x/freertos_adapt_mcu.c'
        rtos_src += list(map(lambda x:os.path.join('$SDK_ROOT/soc/',x),[
            'arm_cm/le501x/compiler/$COMPILER/port.c',
            rtos_adapt,
        ]))
        inc_list += ['$SDK_ROOT/rtos/freertos/include']
    if mesh:
        self.Append(LIBS = [File(self.subst('$SDK_ROOT/soc/arm_cm/le501x/bin/libmesh.o'))])
        self['STACK_HEX'] = File(self.subst('$SDK_ROOT/soc/arm_cm/le501x/bin/fw_with_sig_mesh.hex'))
        self['APP_IMAGE_BASE'] = 0x18056000
        if self.get('LINKSCRIPT') is None:
            self['LINKSCRIPT'] = File(self.subst("$SDK_ROOT/soc/arm_cm/le501x/compiler/$COMPILER/mesh.ld"))
    elif ble:
        self.Append(LIBS = [File(self.subst('$SDK_ROOT/soc/arm_cm/le501x/bin/libfw.o'))])
        self['STACK_HEX'] = File(self.subst('$SDK_ROOT/soc/arm_cm/le501x/bin/fw.hex'))
        self['APP_IMAGE_BASE'] = 0x18034000
        if self.get('LINKSCRIPT') is None:
            self['LINKSCRIPT'] = File(self.subst("$SDK_ROOT/soc/arm_cm/le501x/compiler/$COMPILER/ble.ld"))
    else:
        self['APP_IMAGE_BASE'] = 0x18002000
        if self.get('LINKSCRIPT') is None:
            self['LINKSCRIPT'] = File(self.subst("$SDK_ROOT/soc/arm_cm/le501x/compiler/$COMPILER/mcu.ld"))
    self.Append(LIBPATH = [self.subst("$SDK_ROOT/soc/arm_cm/le501x/compiler/$COMPILER/")])
    self.Append(CPPPATH = self.inc_dirs(inc_list))
    target = self.Program('build/le501x/'+name,self.variant_dir_source(sdk_src + start_src + app_src + rtos_src),OBJPREFIX = objprefix)
    self.Depends(target,[self['LINKSCRIPT'],self.subst("$SDK_ROOT/soc/arm_cm/le501x/compiler/$COMPILER/common.ld")])
    return target

env.AddMethod(plf_postaction)
env.AddMethod(plf_build)

